チャネル でのデッドロック
チャネルの capacity は排他的なリソース(読み込みリソースと書き込みリソースのコレクション)と考えられる e.g. バッファなしチャネルの場合
初期状態ではどちらのリソースも存在しない
あるゴルーチンが書き込み操作を行うと、書き込みリソースを獲得しようとする間に、1 つの読み込みリソースを利用可能にする
逆にあるゴルーチンが読み込み操作を行うと、読み込みリソースを獲得しようとする間に、1 つの書き込みリソースを利用可能にする
そのため、ゴルーチンがあるチャネルを保持しながら別のチャネルを使おうとする(メッセージ を送信または受信する)とデッドロックが発生する可能性がある 具体例
https://scrapbox.io/files/67ca71796537906495c4bf00.png
code:go
func handleDirectories(dirs <-chan string, files chan<- string) {
for fullpath := range dirs {
fmt.Println("Reading all files from", fullpath)
filesInDir, _ := os.ReadDir(fullpath)
fmt.Printf("Pushing %d files from %s\n", len(filesInDir), fullpath)
for _, file := range filesInDir {
files <- filepath.Join(fullpath, file.Name())
}
}
}
func handleFiles(files <-chan string, dirs chan<- string) {
for path := range files {
file, _ := os.Open(path)
fileInfo, _ := file.Stat()
if fileInfo.IsDir() {
fmt.Printf("Pushing %s directory\n", fileInfo.Name())
dirs <- path
return
}
fmt.Printf("File %s, size: %.2fKB, last modified: %s\n",
fileInfo.Name(), float64(fileInfo.Size())/1024.0,
fileInfo.ModTime().Format(time.ANSIC))
}
}